package com.athenaeum.datastore.helper;

import java.util.Iterator;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.criterion.ProjectionList;
import org.hibernate.criterion.Projections;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Order;

public class RepositoryPageHelper<T> {
	private String PropertyNameToBeDistinctOnForCount = "id";

	  public Page<T> findPage(Criteria hcriteria, Pageable pageable) {
			
			hcriteria.setMaxResults(pageable.getPageSize());
			hcriteria.setFirstResult((pageable.getPageNumber() - 1) * pageable.getPageSize());
			List<T> results = hcriteria.list();

			// now for the count
			hcriteria.setFirstResult(0); // go back to beginning

			hcriteria.setMaxResults(Integer.MAX_VALUE);

			Sort sort = pageable.getSort();
			if(sort != null) {
				Iterator<Order> iterator = sort.iterator();
				ProjectionList projectionList = Projections.projectionList();
				while(iterator.hasNext()) {
					Order order = iterator.next();
					projectionList.add(Projections.countDistinct(order.getProperty()));
				}
				hcriteria.setProjection(projectionList);
			} else {
				hcriteria.setProjection(Projections.projectionList().add(Projections.countDistinct(PropertyNameToBeDistinctOnForCount)));
			}
			List countList = hcriteria.list();
			int rowCount = 0;
			if (countList.size() > 0) {
				rowCount = ((Long)countList.get(0)).intValue();
			}
			Page currPage = new PageImpl<T>(results, pageable, rowCount);
			return currPage;
		}

	  public String getPropertyNameToBeDistinctOnForCount() {
	    return PropertyNameToBeDistinctOnForCount;
	  }

	  public void setPropertyNameToBeDistinctOnForCount(String propertyNameToBeDistinctOnForCount) {
	    PropertyNameToBeDistinctOnForCount = propertyNameToBeDistinctOnForCount;
	  }
}
